#ifndef FILEPARSER_H
#define FILEPARSER_H

#include "yaml-cpp/parser.h"
#include "yaml-cpp/yaml.h"

#include <QObject>
#include <QFile>
#include <QDebug>
#include "pattern/signleton.hpp"
#include <QJsonObject>
#include <QJsonDocument>
#include <QTreeView>
#include <QStandardItemModel>
#include <QStandardItem>
#include "libxml/xmlmemory.h"
#include "libxml/parser.h"
using namespace  std;

class Q_DECL_EXPORT Parser
{
public:
    Parser();
    virtual int Parse(QString conf){
        this->mFile = new QFile(conf);
        return 0;
    }
    virtual QString DumpString(){
        return "not supposed to call this function for parent class";
    }
    virtual ~Parser() {

    }
    virtual void RenderQTreeView(QTreeView *){};

protected:
    void *mDat;// pointer to the parsed data
    QFile *mFile;
private:
    DECLARE_SINGLETON(Parser)
};

class Q_DECL_EXPORT  JsonParser : public Parser
{
public:
    JsonParser();
    int Parse(QString conf);
    int Parse(QStandardItemModel *model);
    void RenderQModelObject(QStandardItem* model);
    QString ToString(void);

    int _getJsonObjectFromString(QString);
private:
    QJsonObject mObj;
    QJsonDocument mDoc;
    int renderSubJsonQModel(QJsonObject ,QStandardItem* model);
    int renderSubJsonQArray(QJsonArray ,QStandardItem* model);
    int _parseJson(QString);
    int _parseSubQVariant(QVariant,QJsonObject *);
    int _parseSubQVariant(QVariant,QJsonArray *);
    int _parseSubQVariant(QStandardItem*,QJsonArray *);
    int _parseSubQVariant(QStandardItem*,QJsonObject *);

    QJsonValue _QVariantToQjson(QVariant);
    DECLARE_SINGLETON(JsonParser)
    DECLARE_SINGLETON(Parser)
};

class Q_DECL_EXPORT YamlParser :public Parser{
public:
    int Parse(QString conf);
    int Parse(QStandardItemModel* model);
    int _parseSubQVaraintArray(QStandardItem *item, YAML::Node *arr);
    int _parseSubQVaraintMap(QStandardItem *item, YAML::Node *arr);

    void RenderQModelObject(QStandardItem* model);
    YAML::Node &Node();
private:
    int renderSubYamlQModel(QMap<QString,QVariant> &map,YAML::Node  ,QStandardItem* model);
    int renderSubYamlQModel(QList<QVariant> &list,YAML::Node  ,QStandardItem* model);

    YAML::Node _qvariantToNode(QVariant value);
    YAML::Node getYamlNodeFromString(const QString yamlString);
    YAML::Node mNode;
    int _parseYaml(QString) noexcept;
    QVariant _guessType(QString);
    DECLARE_SINGLETON(YamlParser)
    DECLARE_SINGLETON(Parser)
};

class Q_DECL_EXPORT XmlParser :public Parser{
public:
    XmlParser();
    int Parse(QString conf);
    int Parse(QStandardItemModel* model);

    void RenderQModelObject(QStandardItem* model);
    YAML::Node &Node();
    ~XmlParser();
private:
    int _parseXML(QString) noexcept;

    xmlDocPtr mDoc;   //xml整个文档的树形结构
    xmlNodePtr mCur;  //xml节点
    xmlChar *id;     //phone id

    int renderSubXmlQModel(xmlNode *cur_node ,QStandardItem* model);

    QVariant _guessType(QString);
    DECLARE_SINGLETON(YamlParser)
    DECLARE_SINGLETON(Parser)
};

typedef Singletone<JsonParser> gJsonParser;
typedef Singletone<YamlParser> gYamlParser;
typedef Singletone<XmlParser>  gXmlParser;

#endif // FILEPARSER_H
